﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MDX_Studio_v2
{
	using Microsoft.AnalysisServices;
	using Microsoft.AnalysisServices.AdomdClient;
	using System;

	public class SSASConnection
	{
		private Microsoft.AnalysisServices.Server _AMOConnection = null;
		private string _CurrentCatalog = null;
		private string _CurrentCube = null;
		private AdomdConnection _MetadataConnection = null;
		private AdomdConnection _QueryConnection = null;
		private string _ServerName = null;
		private Microsoft.AnalysisServices.Server _TraceConnection = null;

		public string ServerName
		{
			get { return _ServerName; }
			set { _ServerName = value; }
		}

		public string Catalog
		{
			get { return _CurrentCatalog; }
			set { _CurrentCatalog = value; }
		}

		public string Cube
		{
			get { return _CurrentCube; }
			set { _CurrentCube = value; }
		}

		public AdomdConnection QueryConnection
		{
			get { return _QueryConnection; }
			set { }
		}

		public bool StartQueryConnection()
		{
			_QueryConnection = new AdomdConnection(this.GetConnectionString());
			_QueryConnection.Open();
			Console.WriteLine(this.GetConnectionString());
			return true;
		}

		/// <summary>
		/// Connect to the server
		/// Returns true if a connection is made
		/// Returns false if a connection cannot be made, or if no Server Name has been specified
		/// </summary>
		/// <returns></returns>
		public bool ConnectToServer()
		{
			string connectionStr = GetConnectionString();
			if(connectionStr == null) return false;

			try
			{
				_AMOConnection = new Server();
				_AMOConnection.Connect(connectionStr);
			}
			catch (Exception ex)
			{
				Console.WriteLine("SSASConnection.cs\\ConnectToServer: {0}", ex.Message);
				return false;
			}
			return true;
		}

		/// <summary>
		/// Returns a collection of Databases on the SSAS server, if connected
		/// Returns null otherwise
		/// </summary>
		/// <returns></returns>
		public DatabaseCollection ListCatalogs()
		{
			if (_AMOConnection == null) return null;

			return _AMOConnection.Databases;
		}

		/// <summary>
		/// Returns a collection of Cubes within the Catalog, if connected to a server and a valid Catalog is specified
		/// Returns null otherwise
		/// </summary>
		/// <param name="catalog"></param>
		/// <returns></returns>
		public Microsoft.AnalysisServices.CubeCollection ListCubes(string catalog=null)
		{
			if (_AMOConnection == null || catalog == null) return null;

			try
			{
				return _AMOConnection.Databases[catalog].Cubes;
			}
			catch(Exception ex)
			{
				Console.WriteLine("SSASConnection.cs\\ListCubes: {0}", ex.Message);
				return null;
			}
		}

		public Microsoft.AnalysisServices.Cube GetCube(string cubeName = null)
		{
			if (cubeName == null) cubeName = _CurrentCube;
			if (cubeName == null || _CurrentCatalog == null || _AMOConnection == null) return null;

			try
			{
				foreach (Microsoft.AnalysisServices.Cube x in _AMOConnection.Databases[_CurrentCatalog].Cubes)
					if (x.Name == cubeName) return x;
				return null;
			}
			catch (Exception ex)
			{
				Console.WriteLine("SSASConnection.cs\\GetCube: {0}", ex.Message);
				return null;
			}
		}

		public string TryConnect(string server, string catalog, string cube)
		{
			try
			{
				if(server == "" || server == null) return "No valid Server Name provided!";


				// Try to connect to server first
				string connStr = "Provider=MSOLAP;Data Source=" + server + ";";
				Microsoft.AnalysisServices.Server tmpConnection;
				try
				{
					tmpConnection = new Server();
					tmpConnection.Connect(connStr);

					// If connected to server, but no catalog provided
					if(catalog == "" || catalog == null) return "Successfully connected to the server \"" + server + "\"!";
				}
				catch (Exception ex) { return "Could not connect to the server \"" + server + "\"!"; }


				// Try to connect to the server & catalog
				connStr = GetConnectionString(server, catalog);
				try
				{
					tmpConnection = new Server();
					tmpConnection.Connect(connStr);

					// If connected to server & catalog, and no Cube provided
					if(cube == "" || cube == null) return "Successfully connected to the server \"" + server + "\" and catalog \"" + catalog + "\"!";

					// See if Cube exists
					foreach (Cube c in tmpConnection.Databases[catalog].Cubes)
						if (c.Name == cube) return "Connection Successful!";

				}
				catch (Exception ex) { return "Able to connect to the server \"" + server + "\"; but unable to connect to the catalog \"" + catalog + "\"!";}
			}
			catch (Exception ex) { Console.WriteLine("SSASConnection.cs\\TryConnect: {0}", ex.Message); }
			return null;
		}





		/// <summary>
		/// Returns the connection string for the connection settings
		/// Returns null if no Server Name is available
		/// </summary>
		/// <returns></returns>
		public string GetConnectionString()
		{
			if (_ServerName == null)
				return null;
			StringBuilder conStr = new StringBuilder("Provider=MSOLAP;");
			conStr.AppendFormat("Data Source={0};", _ServerName);

			if (_CurrentCatalog != null) conStr.AppendFormat("Initial Catalog={0};", _CurrentCatalog);

			return conStr.ToString();
		}

		/// <summary>
		/// Returns the connection string for the connection settings
		/// Returns null if no Server Name is available
		/// </summary>
		/// <returns></returns>
		private string GetConnectionString(string server, string catalog)
		{
			if (server == null)
				return null;
			StringBuilder conStr = new StringBuilder("Provider=MSOLAP;");
			conStr.AppendFormat("Data Source={0};", server);

			if (_CurrentCatalog != null) conStr.AppendFormat("Initial Catalog={0};", catalog);

			return conStr.ToString();
		}

		/// <summary>
		/// Outputs the Connection as a string; for debug purposes only
		/// </summary>
		/// <returns></returns>
		public override string ToString()
		{
			return String.Format("Server:{0}; Catalog:{1}; Cube:{2}; AMOConn:{3};",
				_ServerName, _CurrentCatalog, _CurrentCube, _AMOConnection );
		}
	}
}
